package mapper

import (
	"context"
	"gorm.io/gorm"
	"mall/services/product/rpc/internal/domain/bo"
	"mall/services/product/rpc/internal/initialize/mysql"
	"mall/services/product/rpc/internal/mapper/entity"
)

var attrAllColumn = "attr_id,create_time, update_time, shop_id, name, `desc`, search_type, attr_type"

type AttrMapper struct {
	ctx context.Context
}

func NewAttrMapper(ctx context.Context) *AttrMapper {
	return &AttrMapper{ctx: ctx}
}

func (m *AttrMapper) SelectCountCtx(db *gorm.DB, attrBO bo.AttrBO) (totalCount int64, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrMapper#SelectCountCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})

	var total int64
	attrEntity := entity.AttrEntity{}
	tx = tx.Select(attrAllColumn).Table(attrEntity.TableName())
	m.getAllWhereSql(tx, attrBO)
	tx.Count(&total)
	return total, tx.Error
}

func (m *AttrMapper) SelectOneCtx(db *gorm.DB, attrBO bo.AttrBO) (returnEntity entity.AttrEntity, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrMapper#SelectOneCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})

	attrEntity := entity.AttrEntity{}
	tx = tx.Select(attrAllColumn).Table(attrEntity.TableName())
	m.getAllWhereSql(tx, attrBO)
	tx.First(&attrEntity)
	if tx.Error == nil || tx.Error.Error() == "record not found" {
		return attrEntity, nil
	}
	return attrEntity, tx.Error
}

func (m *AttrMapper) SelectListCtx(db *gorm.DB, attrBO bo.AttrBO) (returnEntity []entity.AttrEntity, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrMapper#SelectListCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})
	var attrEntityArr []entity.AttrEntity
	tx = tx.Select(attrAllColumn).Table("attr")
	m.getAllWhereSql(tx, attrBO)
	tx = tx.Find(&attrEntityArr)
	return attrEntityArr, tx.Error
}

func (m *AttrMapper) getAllWhereSql(db *gorm.DB, attrBO bo.AttrBO) {
	if attrBO.AttrId > 0 {
		db.Where("attr_id = ?", attrBO.AttrId)
	}
	if attrBO.ShopId != 0 {
		db.Where("shop_id = ?", attrBO.ShopId)
	}
	if len(attrBO.Name) > 0 {
		db.Where("name = ?", attrBO.Name)
	}
	if len(attrBO.NameAllLike) > 0 {
		db.Where("name like ?", "%"+attrBO.NameAllLike+"%")
	}
	if len(attrBO.Desc) > 0 {
		db.Where("desc = ?", attrBO.Desc)
	}
	if attrBO.AttrType != 0 {
		db.Where("attr_type = ?", attrBO.AttrType)
	}
	if attrBO.SearchType != 0 {
		db.Where("search_type = ?", attrBO.SearchType)
	}
	if len(attrBO.StartTime) > 0 {
		db.Where("create_time = ?", attrBO.StartTime)
	}
	if len(attrBO.EndTime) > 0 {
		db.Where("create_time = ?", attrBO.EndTime)
	}
}

func (m *AttrMapper) InsertCtx(tx *gorm.DB, builderEntity entity.AttrEntity) (attrId int64, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrMapper#InsertCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx = tx.Create(&builderEntity)
	return builderEntity.AttrId, tx.Error
}

func (m *AttrMapper) UpdateCtx(tx *gorm.DB, attrEntity entity.AttrEntity) (err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrMapper#UpdateCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx = tx.Where("attr_id = ?", attrEntity.AttrId).UpdateColumns(attrEntity).Omit("attr_id")
	return tx.Error
}

func (m *AttrMapper) DeleteCtx(tx *gorm.DB, attrIdArr []int64) (err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrMapper#DeleteCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	attrEntity := entity.AttrEntity{}
	tx = tx.Where("attr_id in ?", attrIdArr).Delete(&attrEntity)
	return tx.Error
}
